package com.glsc.ngateway.oaflow.service.xirtrade.enums;

import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.xir.domain.Tbnd;
import com.glsc.ngateway.common.xir.domain.TtrdOtcTrade;
import com.glsc.ngateway.common.xir.domain.TtrdSetInstruction;
import com.glsc.ngateway.common.xir.domain.TtrdSetInstructionSecu;
import com.glsc.ngateway.oaflow.service.xirtrade.XirTradeGSBFactory;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.logging.log4j.util.Strings;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 衡泰交易指令业务类型
 *
 * @author xuchang
 */
@Getter
@AllArgsConstructor
public enum 衡泰业务类型枚举_固收部 {
    债券认购_分销买入_首期("61", "债券认购-分销买入-首期",
            () -> DateFormatUtils.format(new Date(), "M月d日") + "固收部存单认购缴款资金划付",
            (context, tbnd, trade) -> Objects.isNull(tbnd) || Objects.isNull(trade) ? Strings.EMPTY :
                    "备注：国联证券认购" + tbnd.getBName() + "(" + tbnd.getICode() + ")" + "债券缴款金额" + trade.getOrdamount() + "元",
            (context, trade) -> trade.getOrdamount(),
            (context, trade) -> trade.getSetdate()
    ),
    债券借贷_定期付息("8101", "债券借贷_定期付息",
            () -> DateFormatUtils.format(new Date(), "M月d日") + "固收部借贷付息划款",
            (context, tbnd, trade) -> Optional.ofNullable(context.getTrade2InstMap().get(trade.getIntordid()))
                    .map(inst -> Optional.ofNullable(context.getInst2SecuMap().get(inst.getInstId()))
                            .map(secu -> "备注：国联证券债券借贷付息划款" + Math.abs(Long.parseLong(secu.getRtLCost())) + "元")
                            .orElse(Strings.EMPTY))
                    .orElse(Strings.EMPTY),
            (context, trade) -> {
                TtrdSetInstruction inst = context.getTrade2InstMap().get(trade.getIntordid());
                if (Objects.nonNull(inst)) {
                    TtrdSetInstructionSecu secu = context.getInst2SecuMap().get(inst.getInstId());
                    if (Objects.nonNull(secu)) {
                        return String.valueOf(Math.abs(Long.parseLong(secu.getRtLCost())));
                    }
                }
                return Strings.EMPTY;
            },
            (context, trade) -> Optional.ofNullable(context.getTrade2InstMap().get(trade.getIntordid()))
                    .map(inst -> Optional.ofNullable(context.getInst2SecuMap().get(inst.getInstId()))
                            .map(TtrdSetInstructionSecu::getBegDate).orElse(null))
                    .orElse(null)

    ),
    债券借贷_到期("91_END", "债券借贷_到期",
            () -> DateFormatUtils.format(new Date(), "M月d日") + "固收部借贷到期划款",
            (context, tbnd, trade) -> Objects.isNull(trade) ? Strings.EMPTY :
                    ("备注：国联证券债券借贷到期划款" +
                            Optional.ofNullable(context.getInst2SecuMap().get(trade.getEndInstId()))
                                    .map(TtrdSetInstructionSecu::getRtLCost).orElse(Strings.EMPTY)
                            + "元"),
            (context, trade) -> Objects.isNull(trade) ? Strings.EMPTY :
                    Optional.ofNullable(context.getInst2SecuMap().get(trade.getEndInstId()))
                            .map(TtrdSetInstructionSecu::getRtLCost).orElse(Strings.EMPTY),
            (context, trade) -> Optional.ofNullable(context.getTrade2InstMap().get(trade.getIntordid())).map(TtrdSetInstruction::getSetdate).orElse(null)
    ),
    ;

    /**
     * 编码
     */
    private final String code;
    /**
     * 描述
     */
    private final String desc;

    /**
     * oa流程title构建方法
     */
    private TitleBuild titleBuilder;
    private RemarkBuild remarkBuilder;
    private PayAmountBuild payAmountBuild;
    private PayDateBuild payDateBuild;

    public static 衡泰业务类型枚举_固收部 seek(String code) {
        return Arrays.stream(衡泰业务类型枚举_固收部.values())
                .filter(o -> o.getCode().equals(code))
                .findFirst()
                .orElseThrow(() -> PlatformException.error(String.format("未找到类型:%s", code)));
    }

    public static List<String> all() {
        return Arrays.stream(衡泰业务类型枚举_固收部.values()).map(衡泰业务类型枚举_固收部::getCode).collect(Collectors.toList());
    }

    public String getTitle() {
        return this.getTitleBuilder().build();
    }

    public String getRemark(XirTradeGSBFactory.BuildContext context, Tbnd tbnd, TtrdOtcTrade trade) {
        return this.getRemarkBuilder().build(context, tbnd, trade);
    }

    public String getPayAmount(XirTradeGSBFactory.BuildContext context, TtrdOtcTrade trade) {
        return this.getPayAmountBuild().build(context, trade);
    }

    public String getPayDate(XirTradeGSBFactory.BuildContext context, TtrdOtcTrade trade) {
        return this.getPayDateBuild().build(context, trade);
    }

    @FunctionalInterface
    private interface TitleBuild {
        String build();
    }

    @FunctionalInterface
    private interface RemarkBuild {
        String build(XirTradeGSBFactory.BuildContext context, Tbnd tbnd, TtrdOtcTrade trade);
    }

    @FunctionalInterface
    private interface PayAmountBuild {
        String build(XirTradeGSBFactory.BuildContext context, TtrdOtcTrade trade);
    }

    @FunctionalInterface
    private interface PayDateBuild {
        String build(XirTradeGSBFactory.BuildContext context, TtrdOtcTrade trade);
    }
}
